You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
10 KiB
353 lines
10 KiB
3 years ago
|
# Ingress 指南
|
||
|
|
||
|
AUTHOR: 彭玲 TIME: 2022/6/8
|
||
|
|
||
|
---
|
||
|
|
||
|
[TOC]
|
||
|
|
||
|
---
|
||
|
|
||
|
|
||
|
|
||
|
## Ingress 是什么?
|
||
|
|
||
|
Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。流量路由由 Ingress 资源上定义的规则控制。下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
|
||
|
|
||
|
![](D:/WorkSpace/iBlog/K8s/assets/Ingress:简单示例.jpg)
|
||
|
|
||
|
|
||
|
|
||
|
## Ingress 资源
|
||
|
|
||
|
Ingress 经常使用`注解`来配置一些选项,不同的 `Ingress 控制器`支持不同的`注解`,具体取决于 Ingress 控制器。
|
||
|
|
||
|
Ingress 规约提供了配置`负载均衡器`或者`代理服务器`所需的所有信息。最重要的是,其中包含与所有`传入请求`匹配的规则列表。
|
||
|
|
||
|
一个最小的 Ingress 资源示例:
|
||
|
|
||
|
```yaml
|
||
|
apiVersion: networking.k8s.io/v1
|
||
|
kind: Ingress
|
||
|
metadata:
|
||
|
name: minimal-ingress
|
||
|
annotations:
|
||
|
nginx.ingress.kubernetes.io/rewrite-target: /
|
||
|
spec:
|
||
|
rules:
|
||
|
- http:
|
||
|
paths:
|
||
|
- path: /testpath
|
||
|
pathType: Prefix
|
||
|
backend:
|
||
|
service:
|
||
|
name: test
|
||
|
port:
|
||
|
number: 80
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
## Ingress 规则
|
||
|
|
||
|
每个 HTTP 规则都包含以下信息:
|
||
|
|
||
|
- **`host`**(可选) 。在上面的`一个最小的 Ingress 资源示例`中未指定 `host`,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了`host`(例如`foo.bar.com`),则`rules`适用于该`host`。
|
||
|
- **`paths`**路径列表 (例如`/testpath`),每个`路径`都有一个由`serviceName`和`servicePort`定义的关联后端。在`负载均衡器`将流量定向到引用的 Service 之前,host 和 path 都必须匹配`传入请求`的内容。
|
||
|
- **`backend`**(后端) 是`Service`和`端口名称`的组合。对 Ingress 的 HTTP (和 HTTPS) 请求 (该请求与 rule 的`host`和`path`匹配) 将发送到列出的`backend`。
|
||
|
|
||
|
|
||
|
|
||
|
## 主机名通配符
|
||
|
|
||
|
主机名可以是`精确`匹配(例如 “`foo.bar.com`”)或者使用`通配符`来匹配 (例如 “`*.foo.com`”)。
|
||
|
|
||
|
- 精确匹配 要求 HTTP `host`头部字段 与 `host`字段值 完全匹配。
|
||
|
- 通配符匹配 则要求 HTTP `host`头部字段 与 通配符规则中的`后缀`部分相同。
|
||
|
|
||
|
```yaml
|
||
|
apiVersion: networking.k8s.io/v1
|
||
|
kind: Ingress
|
||
|
metadata:
|
||
|
name: ingress-wildcard-host
|
||
|
spec:
|
||
|
rules:
|
||
|
- host: "foo.bar.com"
|
||
|
http:
|
||
|
paths:
|
||
|
- pathType: Prefix
|
||
|
path: "/bar"
|
||
|
backend:
|
||
|
service:
|
||
|
name: service1
|
||
|
port:
|
||
|
number: 80
|
||
|
- host: "*.foo.com"
|
||
|
http:
|
||
|
paths:
|
||
|
- pathType: Prefix
|
||
|
path: "/foo"
|
||
|
backend:
|
||
|
service:
|
||
|
name: service2
|
||
|
port:
|
||
|
number: 80
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
## Ingress 配置
|
||
|
|
||
|
在 `ingress` 中`配置`分为了三部分:
|
||
|
|
||
|
- `configmap`:设置 ingress-nginx 的全局设置。
|
||
|
- `annotations`:ingress 特定的设置。
|
||
|
- `custom template`。
|
||
|
|
||
|
### 1. 全局设置 (`ConfigMap`)
|
||
|
|
||
|
全局配置一般是使用 configmap 。
|
||
|
|
||
|
#### ingress-controller 配置文件
|
||
|
|
||
|
下面是一个 ingress-controller 的配置:
|
||
|
|
||
|
```yaml
|
||
|
kind: ConfigMap
|
||
|
apiVersion: v1
|
||
|
metadata:
|
||
|
name: ingress-nginx-controller
|
||
|
namespace: ingress-nginx
|
||
|
labels:
|
||
|
app.kubernetes.io/component: controller
|
||
|
app.kubernetes.io/instance: ingress-nginx
|
||
|
app.kubernetes.io/managed-by: Helm
|
||
|
app.kubernetes.io/name: ingress-nginx
|
||
|
app.kubernetes.io/version: 0.40.2
|
||
|
helm.sh/chart: ingress-nginx-3.6.0
|
||
|
annotations:
|
||
|
data:
|
||
|
allow-backend-server-header: 'true'
|
||
|
client-body-buffer-size: 20m
|
||
|
enable-underscores-in-headers: 'true'
|
||
|
generate-request-id: 'true'
|
||
|
gzip-level: '6'
|
||
|
gzip-types: >-
|
||
|
application/atom+xml application/javascript application/x-javascript
|
||
|
application/json application/rss+xml application/vnd.ms-fontobject
|
||
|
application/x-font-ttf application/x-web-app-manifest+json
|
||
|
application/xhtml+xml application/xml font/opentype image/svg+xml
|
||
|
image/x-icon text/css text/javascript text/plain text/x-component
|
||
|
ignore-invalid-headers: 'true'
|
||
|
keep-alive: '75'
|
||
|
large-client-header-buffers: 4 128k
|
||
|
log-format-upstream: >-
|
||
|
$remote_addr - [$remote_addr] - $remote_user [$time_local] "$request"
|
||
|
$status $body_bytes_sent "$http_referer" "$http_user_agent" $request_length
|
||
|
"$http_x_forwarded_for" $remote_addr $request_time [$proxy_upstream_name]
|
||
|
$upstream_addr $upstream_response_length $upstream_response_time
|
||
|
$upstream_status $req_id $host
|
||
|
max-worker-connections: '65536'
|
||
|
proxy-body-size: 20m
|
||
|
proxy-buffer-size: 64k
|
||
|
proxy-connect-timeout: '300'
|
||
|
proxy-next-upstream-timeout: '10'
|
||
|
proxy-read-timeout: '300'
|
||
|
proxy-send-timeout: '300'
|
||
|
reuse-port: 'true'
|
||
|
server-tokens: 'false'
|
||
|
upstream-keepalive-connections: '20000'
|
||
|
upstream-keepalive-requests: '100000'
|
||
|
upstream-keepalive-timeout: '3000'
|
||
|
use-forwarded-headers: 'true'
|
||
|
use-gzip: 'true'
|
||
|
worker-cpu-affinity: auto
|
||
|
```
|
||
|
|
||
|
#### nginx 配置文件 (`nginx.conf`)
|
||
|
|
||
|
上面的 ingress-controller 配置,相当于 `nginx` 的 `nginx.conf` 配置文件:
|
||
|
|
||
|
```
|
||
|
user www-data;
|
||
|
worker_processes auto;
|
||
|
pid /run/nginx.pid;
|
||
|
include /etc/nginx/modules-enabled/*.conf;
|
||
|
|
||
|
events {
|
||
|
worker_connections 768;
|
||
|
multi_accept on;
|
||
|
}
|
||
|
|
||
|
http {
|
||
|
|
||
|
##
|
||
|
# Basic Settings
|
||
|
##
|
||
|
|
||
|
sendfile on;
|
||
|
tcp_nopush on;
|
||
|
tcp_nodelay on;
|
||
|
keepalive_timeout 65;
|
||
|
types_hash_max_size 2048;
|
||
|
server_tokens off;
|
||
|
|
||
|
# server_names_hash_bucket_size 64;
|
||
|
# server_name_in_redirect off;
|
||
|
|
||
|
include /etc/nginx/mime.types;
|
||
|
default_type application/octet-stream;
|
||
|
|
||
|
##
|
||
|
# SSL Settings
|
||
|
##
|
||
|
|
||
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
|
||
|
ssl_prefer_server_ciphers on;
|
||
|
|
||
|
##
|
||
|
# Logging Settings
|
||
|
##
|
||
|
|
||
|
access_log /var/log/nginx/access.log;
|
||
|
error_log /var/log/nginx/error.log;
|
||
|
|
||
|
##
|
||
|
# body size
|
||
|
##
|
||
|
client_max_body_size 10m;
|
||
|
proxy_read_timeout 300;
|
||
|
|
||
|
##
|
||
|
# Gzip Settings
|
||
|
##
|
||
|
|
||
|
gzip on;
|
||
|
gzip_vary on;
|
||
|
gzip_proxied any;
|
||
|
gzip_comp_level 6;
|
||
|
gzip_buffers 16 8k;
|
||
|
gzip_http_version 1.1;
|
||
|
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
|
||
|
|
||
|
##
|
||
|
# Virtual Host Configs
|
||
|
##
|
||
|
|
||
|
include /etc/nginx/conf.d/*.conf;
|
||
|
include /etc/nginx/sites-enabled/*;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### 2. 注解 (annotations)
|
||
|
|
||
|
`注解`都是以**`nginx.ingress.kubernetes.io`**作为`前缀`添加到特定的 ingress 实例上的。
|
||
|
|
||
|
#### 身份验证
|
||
|
|
||
|
```yaml
|
||
|
# http 身份验证的类型
|
||
|
nginx.ingress.kubernetes.io/auth-type: [basic|digest]
|
||
|
|
||
|
# Secret的名称,其中包含用户名和密码
|
||
|
nginx.ingress.kubernetes.io/auth-secret: secretName
|
||
|
|
||
|
# auth-secret 有两种格式:
|
||
|
# auth-file 默认情况下,密钥'auth'中的htpasswd文件在密钥内
|
||
|
# auth-map 密钥的密钥是用户名,值是哈希密码
|
||
|
nginx.ingress.kubernetes.io/auth-secret-type: [auth-file|auth-map]
|
||
|
|
||
|
nginx.ingress.kubernetes.io/auth-realm: "realm string"
|
||
|
```
|
||
|
|
||
|
#### 金丝雀
|
||
|
|
||
|
```yaml
|
||
|
nginx.ingress.kubernetes.io/canary-by-header
|
||
|
nginx.ingress.kubernetes.io/canary-by-header-value
|
||
|
nginx.ingress.kubernetes.io/canary-by-cookie
|
||
|
nginx.ingress.kubernetes.io/canary-by-cookie
|
||
|
```
|
||
|
|
||
|
#### Rewrite
|
||
|
|
||
|
在某些情况下,后端服务中公开的 URL 与 Ingress 规则中指定的路径不同。没有重写,任何请求都将返回`404`。设置 `nginx.ingress.kubernetes.io/rewrite-target` 注解到服务期望的路径。如果应用程序`根目录`暴露在其他路径中,并且需要重定向,请设置注释`nginx.ingress.kubernetes.io/app-root`重定向请求到 `/`。
|
||
|
|
||
|
#### Server snippet
|
||
|
|
||
|
使用注解 `nginx.ingress.kubernetes.io/server-snippet` 可以在服务器配置块中添加自定义配置。
|
||
|
|
||
|
```yaml
|
||
|
apiVersion: extensions/v1beta1
|
||
|
kind: Ingress
|
||
|
metadata:
|
||
|
annotations:
|
||
|
nginx.ingress.kubernetes.io/server-snippet: |
|
||
|
set $agentflag 0;
|
||
|
|
||
|
if ($http_user_agent ~* "(Mobile)" ){
|
||
|
set $agentflag 1;
|
||
|
}
|
||
|
|
||
|
if ( $agentflag = 1 ) {
|
||
|
return 301 https://m.example.com;
|
||
|
}
|
||
|
```
|
||
|
|
||
|
#### Configuration snippet
|
||
|
|
||
|
使用此注释,您可以将其他`配置`添加到 NGINX 位置。例如:
|
||
|
|
||
|
```yaml
|
||
|
nginx.ingress.kubernetes.io/configuration-snippet: |
|
||
|
more_set_headers "Request-Id: $req_id";
|
||
|
```
|
||
|
|
||
|
#### Client Body Buffer Size
|
||
|
|
||
|
设置缓冲区大小,以读取每个位置的客户端请求正文。如果请求主体大于缓冲区,整个 Body 或只将其一部分写入一个临时文件。默认情况下,缓冲区大小等于两个内存页。在 x86、其他 32 位平台和 x86-64 上为 8K。在其他 64 位平台上通常为 16K。
|
||
|
|
||
|
该注解是 应用于入口规则中提供的每个位置。
|
||
|
|
||
|
```yaml
|
||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: "1000" # 1000 bytes
|
||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 1k # 1 kilobyte
|
||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 1K # 1 kilobyte
|
||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 1m # 1 megabyte
|
||
|
nginx.ingress.kubernetes.io/client-body-buffer-size: 1M # 1 megabyte
|
||
|
```
|
||
|
|
||
|
#### Redirect from/to www
|
||
|
|
||
|
在某些情况下,需要从 www.domain.com 重定向到`domain.com`,反之亦然。
|
||
|
|
||
|
使用 `nginx.ingress.kubernetes.io/from-to-www-redirect: "true"` 注解开启此功能。
|
||
|
|
||
|
#### Custom timeouts
|
||
|
|
||
|
使用配置 configmap 可以为`ingress-nginx`设置默认的全局超时。在某些情况下,要求具有不同的值。为此,允许自定义注释:
|
||
|
|
||
|
```
|
||
|
nginx.ingress.kubernetes.io/proxy-connect-timeout
|
||
|
nginx.ingress.kubernetes.io/proxy-send-timeout
|
||
|
nginx.ingress.kubernetes.io/proxy-read-timeout
|
||
|
nginx.ingress.kubernetes.io/proxy-next-upstream
|
||
|
nginx.ingress.kubernetes.io/proxy-next-upstream-timeout
|
||
|
nginx.ingress.kubernetes.io/proxy-next-upstream-tries
|
||
|
nginx.ingress.kubernetes.io/proxy-request-buffering
|
||
|
```
|
||
|
|
||
|
#### Custom max body size
|
||
|
|
||
|
当请求中的大小超过客户端请求正文的最大允许大小时,将向客户端返回`413`错误。大小可以通过`client_max_body_size`参数配置。
|
||
|
与上面类似,想要对所有 ingress 规则进行全局设置,可以在 nginx ConfigMap 中设置`proxy-body-size`。要在 Ingress 规则中使用自定义值,请定义以下注解:
|
||
|
|
||
|
```yaml
|
||
|
nginx.ingress.kubernetes.io/proxy-body-size: 8m
|
||
|
```
|
||
|
|
||
|
### 3. custom template
|
||
|
|
||
|
暂无。
|
||
|
|